package zhou.chs.p9_4;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    TextView tv;  //显示读取到的寄存器值
    EditText et;  //编辑写入寄存器的值
    Button btread,btwrite; //按钮
    private Handler myhandler;       //信息通道
    private Socket mSocket;     //Socket
    private StartThread st;     //TCP客户端线程
    private ConnectedThread rt; //TCP数据交换线程
    boolean running = false;
    byte[] rbuf = new byte[256];  //接收缓冲区
    byte[] tbuf; //发送缓冲区
    byte[] tcpbuf = {(byte)0x46,(byte)0x49,(byte)0x4E,(byte)0x53,
            (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x0C,
            (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
            (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00};
    byte[] qbuf = {(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x08};
    byte[] finsbuf = {(byte)0x80,(byte)0x00,(byte)0x02,(byte)0x00,
            (byte)0x01,(byte)0x00,(byte)0x00,(byte)0x08,
            (byte)0x00,(byte)0x00,(byte)0x01,(byte)0x01,
            (byte)0x82,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x02};
    int len;    //接收区字节数
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView)findViewById(R.id.idtv);   //实例化控件
        et = (EditText)findViewById(R.id.idet);
        btread = (Button) findViewById(R.id.idread);
        btwrite = (Button) findViewById(R.id.idwrite);
        btread.setOnClickListener(this);    //注册按钮单击事件
        btwrite.setOnClickListener(this);
        btread.setEnabled(false);   //按钮在连接请求成功后才有效
        btwrite.setEnabled(false);
        myhandler = new MyHandler();     //实例化Handler，用于进程间的通信
        st = new StartThread();
        st.start();  //进入TCP Client线程
    }
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.idread:  //读取按钮
                tbuf = new byte[34];
                tcpbuf[7] = 0x1A; //长度
                tcpbuf[11] = 0x02; //命令码
                for(int i=0;i<16;i++) tbuf[i]=tcpbuf[i];
                finsbuf[11] = 0x01; //读寄存器
                finsbuf[14] = 0x00; //起始地址
                for(int i=0;i<18;i++) tbuf[16+i]=finsbuf[i];
                rt.write(tbuf);  //发送读寄存器命令
                break;
            case R.id.idwrite:  //写入按钮
                tbuf = new byte[38];
                tcpbuf[7] = 0x1E; //长度
                tcpbuf[11] = 0x02; //命令码
                for(int i=0;i<16;i++) tbuf[i]=tcpbuf[i];
                finsbuf[11] = 0x02; //写寄存器
                finsbuf[14] = 0x02; //起始地址
                for(int i=0;i<18;i++) tbuf[16+i]=finsbuf[i];
                String s = et.getText().toString();  //待写入数据
                len = s.length();
                for (int i = 0; i < len; i += 2) {
                    tbuf[34+i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
                }
                rt.write(tbuf);  //发送写寄存器命令
                break;
        }
    }
    //在主线程处理Handler传回来的message
    class MyHandler extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:     // 建立Socket连接
                    tbuf = new byte[20];
                    tcpbuf[7] = 0x0C; //长度
                    tcpbuf[11] = 0x00; //命令码
                    for(int i=0;i<16;i++) tbuf[i]=tcpbuf[i];
                    for(int i=0;i<4;i++) tbuf[16+i]=qbuf[i];
                    rt.write(tbuf);  //发送链接请求
                    break;
                case 1:     // 收到数据
                    if((rbuf[11]==1)&&(rbuf[15]==0)){   //连接请求通过
                        btread.setEnabled(true);  //按钮使能，可以读写数据
                        btwrite.setEnabled(true);
                    }
                    if((rbuf[11]==2)&&(rbuf[15]==0)&&(rbuf[27]==1)){   //收到读寄存器响应帧
                        String s = "";
                        for(int i=0;i<4;i++){
                            s = s + String.format("%02X",rbuf[30+i]);
                        }
                        tv.setText(s);  //显示收到数据
                    }
                    break;
            }
        }
    }
    // TCP Client连接线程
    private class StartThread extends Thread{
        @Override
        public void run() {
            try {       //连接服务端的IP地址和端口
                mSocket = new Socket("192.168.250.1",9600);
                rt = new ConnectedThread(mSocket);//启动接收数据的线程
                rt.start();
                running = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    // TCP数据传输线程
    private class ConnectedThread extends Thread {
        private final Socket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        public ConnectedThread(Socket socket) {   //socket连接
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            try {
                tmpIn = mmSocket.getInputStream();      //数据通道创建
                tmpOut = mmSocket.getOutputStream();
                Message msg0 = myhandler.obtainMessage();
                msg0.what = 0;
                myhandler.sendMessage(msg0);
            } catch (IOException e) { }
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }
        public final void run() {
            while (running) {
                int byt;
                try {
                    byt = mmInStream.read(rbuf);     // 监听接收到的数据
                    if(byt>0){
                        Message msg1 = myhandler.obtainMessage();
                        msg1.what = 1;
                        msg1.obj=byt;
                        myhandler.sendMessage(msg1); // 通知主线程接收到数据
                        try{
                            sleep(200);
                        }catch (InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                } catch (NullPointerException e) {
                    running = false;
                    e.printStackTrace();
                    break;
                } catch (IOException e) {
                    break;
                }
            }
        }
        public void write(byte[] bytes) {       //发送字节数据
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) { }
        }
        public void cancel() {      //关闭连接
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }
    @Override   //程序退出前关闭Socket
    protected void onDestroy() {
        super.onDestroy();
        rt.cancel();
    }
}
